package com.cheer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cheer.dao.*;
import com.cheer.dto.*;
import com.cheer.entity.*;
import com.cheer.enums.*;
import com.cheer.exception.ServiceException;
import com.cheer.manager.AccountManager;
import com.cheer.properties.DocumentProperties;
import com.cheer.security.UserInfoHolder;
import com.cheer.service.ApplicantService;
import com.cheer.service.OrganizationService;
import com.cheer.service.ReferenceReviewLogService;
import com.cheer.service.ReferenceService;
import com.cheer.util.ExcelUtil;
import com.cheer.vo.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ApplicantServiceImpl extends ServiceImpl<ApplicantDao, Applicant> implements ApplicantService {

    @Autowired
    private ApplicantDao applicantDao;

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private OrganizationDao organizationDao;

    @Autowired
    private StandingBookDao standingBookDao;

    @Autowired
    private StandingBookDocumentDao standingBookDocumentDao;

    @Autowired
    private StandingBookReviewDao standingBookReviewDao;

    @Autowired
    private StandingBookReviewLogDao standingBookReviewLogDao;

    @Autowired
    private AdminDao adminDao;

    @Autowired
    private AccountManager accountManager;

    @Autowired
    private DocumentProperties documentProperties;

    @Autowired
    private UserInfoHolder userInfoHolder;

    @Autowired
    private ReferenceReviewLogService referenceReviewLogService;

    @Autowired
    private ReferenceService referenceService;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private ReferenceDao referenceDao;


    @Override
    public ApplicantVO getByAccountId(Long accountId) {
        // 查询账号、集体、机构信息
        Account account = accountDao.selectById(accountId);
        if (account == null) {
            throw new ServiceException("账号已失效");
        }
        Applicant applicant = applicantDao.getByAccountId(accountId);
        if (applicant == null) {
            throw new ServiceException("账号下不存在有效的集体信息");
        }
        Organization organization = organizationDao.selectById(applicant.getOrgId());
        if (organization == null) {
            throw new ServiceException("集体所在的组织机构已失效");
        }
        Organization joinOrg = null;
        if (applicant.getReviewType() == ReviewTypeEnum.JOIN.getCode()) {
            joinOrg = organizationDao.selectById(applicant.getJoinReviewOrgId());
            if (joinOrg == null) {
                throw new ServiceException("联合审核机构不存在或已失效");
            }
        }
        ApplicantVO applicantVO = ApplicantVO.build(account, applicant, organization, joinOrg, documentProperties.getUrl());

        // 查询当前机构
        if(OrgTypeEnum.INDUSTRY.getCode() == organization.getOrgType()){
            applicantVO.setIsShowReviewType(true);
        }else{
            applicantVO.setIsShowReviewType(false);
        }
        // 是否允许
        ReferenceEntity referenceEntity = referenceDao.selectByApplicantId(applicant.getId(), DateUtil.format(new Date(), "yyyy"));
        if(referenceEntity == null || referenceEntity.getIsApply() == TrueOrFalseEnum.FALSE.getType()){
            applicantVO.setIsAllowProvince(true);
        }else{
            applicantVO.setIsAllowProvince(false);
        }

        return applicantVO;
    }

    @Override
    public RegisterVO getRegisterByAccountId(Long accountId) {
        // 查询集体、机构信息
        Applicant applicant = applicantDao.getByAccountId(accountId);
        if (applicant == null) {
            throw new ServiceException("账号下不存在有效的集体信息");
        }
        Organization organization = organizationDao.selectById(applicant.getOrgId());
        if (organization == null) {
            throw new ServiceException("集体所在的组织机构已失效");
        }
        Organization joinOrg = null;
        if (applicant.getReviewType() == ReviewTypeEnum.JOIN.getCode()) {
            joinOrg = organizationDao.selectById(applicant.getJoinReviewOrgId());
            if (joinOrg == null) {
                throw new ServiceException("联合审核机构不存在或已失效");
            }
        }
        // 返回数据处理
        return RegisterVO.build(applicant, organization, joinOrg);
    }

    @Override
    public void updateApplicant(Long accountId, ApplicantUpdateDTO applicantUpdateDTO) {
        // 验证参数
        if (applicantUpdateDTO.getYouthNumber() > applicantUpdateDTO.getPersonNumber()) {
            throw new ServiceException("青年人数不能大于职工人数");
        }
        if (applicantUpdateDTO.getYouthNumber() * 2 < applicantUpdateDTO.getPersonNumber()) {
            throw new ServiceException("青年人数比例不能低于 50%");
        }
        if(DateUtil.compare(applicantUpdateDTO.getContactPersonBirth(), new Date()) > 0){
            throw new ServiceException("出生日期必须小于当前日期");
        }
        if (DateUtil.ageOfNow(applicantUpdateDTO.getContactPersonBirth()) >= 40) {
            throw new ServiceException("号长年龄必须小于 40 岁");
        }
        if (applicantUpdateDTO.getAwarded()) {
            if (applicantUpdateDTO.getTitle() == null || !TitleEnum.isValidTitle(applicantUpdateDTO.getTitle())) {
                throw new ServiceException("请选择有效的文明号级别");
            }
            if (applicantUpdateDTO.getTitleYear() == null) {
                throw new ServiceException("请选择获奖年份");
            }
        }
        // 查询修改前的集体信息
        Applicant source = applicantDao.getByAccountId(accountId);
        if (source == null) {
            throw new ServiceException("账号下不存在有效的集体信息");
        }
        // 验证集体名称
        if (!StringUtils.equals(applicantUpdateDTO.getApplicantName(), source.getApplicantName())) {
            if (applicantDao.getByApplicantName(applicantUpdateDTO.getApplicantName()) != null) {
                throw new ServiceException("集体名称已存在");
            }
        }
        // 验证机构
        Organization organization = null;
        if (Objects.equals(applicantUpdateDTO.getOrgId(), source.getOrgId()) == false) {
            organization = organizationDao.selectById(applicantUpdateDTO.getOrgId());
            if (organization == null) {
                throw new ServiceException("选择的组织机构已失效");
            }
        }else{
            organization = organizationDao.selectById(source.getOrgId());
        }
        Organization joinOrg = null;
        if (applicantUpdateDTO.getReviewType() == ReviewTypeEnum.JOIN.getCode()) {
            joinOrg = organizationDao.selectById(applicantUpdateDTO.getJoinReviewOrgId());
            if (joinOrg == null) {
                throw new ServiceException("联合审核机构不存在或已失效");
            }
        }
        // 更新数据
        Applicant applicant = applicantUpdateDTO.build(source, organization, joinOrg);
        updateById(applicant);
    }

    @Override
    public Page<ApplicantPageVO> getPage(Integer pageNum, Integer pageSize, Long orgId, String applicantName,
                                         String contactPerson, Integer title) {

        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            return null;
        }
        applicantName = StringUtils.trimToNull(applicantName);
        contactPerson = StringUtils.trimToNull(contactPerson);

        PageHelper.startPage(pageNum, pageSize);
        List<ApplicantPageDTO> applicantDTOS = applicantDao.listPage(organization.getOrgPath(), applicantName, contactPerson, title);
        PageInfo<ApplicantPageDTO> pageInfo = new PageInfo<>(applicantDTOS);

        List<ApplicantPageVO> applicantVOS = applicantDTOS.stream().map(ApplicantPageDTO::build).collect(Collectors.toList());
        return new Page<ApplicantPageVO>().setPageNum(pageInfo.getPageNum())
                .setPageSize(pageInfo.getPageSize())
                .setPages(pageInfo.getPages())
                .setTotal(pageInfo.getTotal())
                .setContent(applicantVOS);
    }



    @Override
    public void download(Long orgId, String applicantName, String contactPerson, Integer title) {
        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            ExcelUtil.export(new ArrayList<>(), ApplicantExportVO.getHeaderAlias(), "集体信息.xlsx");
            return;
        }
        applicantName = StringUtils.trimToNull(applicantName);
        contactPerson = StringUtils.trimToNull(contactPerson);

        List<ApplicantPageDTO> applicantDTOS = applicantDao.listPage(organization.getOrgPath(), applicantName, contactPerson, title);
        List<ApplicantPageVO> applicantVOS = applicantDTOS.stream().map(ApplicantPageDTO::build).collect(Collectors.toList());

        List<ApplicantExportVO> applicantExportVOS = ApplicantExportVO.buildList(applicantVOS);
        ExcelUtil.export(applicantExportVOS, ApplicantExportVO.getHeaderAlias(), "集体信息.xlsx");
    }

    @Override
    public Page<ApplicantRegisterVO> createSubmitAgain(Integer pageNum, Integer pageSize, Long adminOrgId) {

        // 参数预处理
        Organization organization = organizationDao.selectById(adminOrgId);
        if (organization == null) {
            return null;
        }
        // 查询驳回后提交的集体记录
        List<Long> applicantIds = getCreateSubmitAgainIds();

        // 分页查询
        PageHelper.startPage(pageNum, pageSize);
        List<ApplicantReviewPageDTO> applicantDTOS = applicantDao.createSubmitAgainIdsPage(organization.getOrgPath(), applicantIds);
        PageInfo<ApplicantReviewPageDTO> pageInfo = new PageInfo<>(applicantDTOS);

        // 返回数据处理
        List<ApplicantRegisterVO> applicantVOS = applicantDTOS.stream()
                .map(ApplicantReviewPageDTO::build)
                .collect(Collectors.toList());
        return new Page<ApplicantRegisterVO>().setPageNum(pageInfo.getPageNum())
                .setPageSize(pageInfo.getPageSize())
                .setPages(pageInfo.getPages())
                .setTotal(pageInfo.getTotal())
                .setContent(applicantVOS);
    }

    @Override
    public Integer createSubmitAgainNumber(Long adminOrgId) {
        // 参数预处理
        Organization organization = organizationDao.selectById(adminOrgId);
        if (organization == null) {
            return null;
        }
        // 查询驳回后提交的集体记录
        List<Long> applicantIds = getCreateSubmitAgainIds();
        // 分页查询
        if(CollectionUtils.isEmpty(applicantIds)){
            return applicantIds.size();
        }
        List<ApplicantReviewPageDTO> applicantDTOS = applicantDao.createSubmitAgainIdsPage(organization.getOrgPath(), applicantIds);

        return applicantDTOS.size();
    }

    private List<Long> getCreateSubmitAgainIds() {

        List<Long> appIds = new ArrayList<>();
        List<Applicant> applicants = applicantDao.getByType(RegisterStatusEnum.PROVINCE.getCode());
        // 查询包含不通过的并且当前状态是已经提交的
        if(CollectionUtils.isEmpty(applicants)){
            return appIds;
        }else{
            appIds = applicants.stream().map(Applicant::getId).collect(Collectors.toList());
        }
        List<StandingBookReviewLog> standingBookReviewLogs = standingBookReviewLogDao
                .selectDenyByApplicantIds(appIds, "不通过", RegisterStatusEnum.PROVINCE_TITLE.getCode());
        // 获取最大ID值
        appIds = standingBookReviewLogs.stream().map(StandingBookReviewLog::getApplicantId).distinct().collect(Collectors.toList());
        if(CollectionUtils.isEmpty(appIds)){
            return appIds;
        }
        List<StandingBookReviewLog> lists = standingBookReviewLogDao.selectByApplicantIdsAndAction(appIds, "提交");
        appIds = lists.stream().map(StandingBookReviewLog::getApplicantId).collect(Collectors.toList());

        return appIds;
    }


    @Override
    public Page<ApplicantRegisterVO> getReviewPage(Integer pageNum, Integer pageSize, Long orgId, String applicantName,
                                                   String contactPerson, Integer status, Integer applicantStatus,
                                                   Boolean submitted, Integer reviewType, Integer registerStatus,
                                                   Date startTime, Date endTime) {
        // 参数预处理
        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            return null;
        }
        applicantName = StringUtils.trimToNull(applicantName);
        contactPerson = StringUtils.trimToNull(contactPerson);

        // 分页查询
        PageHelper.startPage(pageNum, pageSize);
        List<ApplicantReviewPageDTO> applicantDTOS = applicantDao.listReviewPage(organization.getOrgPath(), applicantName,
                contactPerson, status, applicantStatus, submitted, reviewType, registerStatus, startTime, endTime);
        PageInfo<ApplicantReviewPageDTO> pageInfo = new PageInfo<>(applicantDTOS);

        // 返回数据处理
        List<ApplicantRegisterVO> applicantVOS = applicantDTOS.stream()
                .map(ApplicantReviewPageDTO::build)
                .collect(Collectors.toList());
        return new Page<ApplicantRegisterVO>().setPageNum(pageInfo.getPageNum())
                .setPageSize(pageInfo.getPageSize())
                .setPages(pageInfo.getPages())
                .setTotal(pageInfo.getTotal())
                .setContent(applicantVOS);
    }

    @Override
    public Page<ApplicantReferenceListVO> getApplicantReferenceList( Integer pageNum, Integer pageSize, Integer vintage,
                                                                     Long orgId, Integer isPost, Integer registerStatus,
                                                                     String applicantName, String contactPerson) {
        // 参数预处理
        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            return null;
        }
        applicantName = StringUtils.trimToNull(applicantName);
        contactPerson = StringUtils.trimToNull(contactPerson);
        // 获取当前用户的身份权限
        List<ApplicantReferenceListVO> applicantReferenceListVOS = selectByRole(pageNum, pageSize, organization.getOrgPath(), vintage,  isPost,
                registerStatus, contactPerson,  applicantName);
        PageInfo<ApplicantReferenceListVO> pageInfo = new PageInfo<>(applicantReferenceListVOS);

        // 返回数据处理
        for (ApplicantReferenceListVO applicantReferenceListVO : applicantReferenceListVOS) {
            applicantReferenceListVO.build();
            ReferenceEntity referenceEntity = referenceService.getById(applicantReferenceListVO.getId());
            ReferenceDetailVO referenceDetailVO = referenceService.detail(referenceEntity);
            applicantReferenceListVO.setRecommend(referenceDetailVO.getRecommend());
            applicantReferenceListVO.setStory(referenceDetailVO.getStory());
            applicantReferenceListVO.setEvidences(referenceDetailVO.getEvidences());
            applicantReferenceListVO.setEvidenceLinks(referenceDetailVO.getEvidenceLinks());
            
            // 联合审批是否提交单独控制
            if(referenceEntity.getReviewType().equals(ReviewTypeEnum.JOIN.getCode())){

                Organization userOrg = organizationDao.selectById(userInfoHolder.getAdminOrgId());
                if(referenceEntity.getBusiPass().equals(TrueOrFalseEnum.TRUE.getType())
                        && referenceEntity.getOrgPath().contains(userOrg.getOrgPath())){
                    applicantReferenceListVO.setIsPost(TrueOrFalseEnum.TRUE.getType());
                }
            }
        }
        return new Page<ApplicantReferenceListVO>().setPageNum(pageInfo.getPageNum())
                .setPageSize(pageInfo.getPageSize())
                .setPages(pageInfo.getPages())
                .setTotal(pageInfo.getTotal())
                .setContent(applicantReferenceListVOS);
    }

    private List<ApplicantReferenceListVO> selectByRole(Integer pageNum, Integer pageSize, String orgPath, Integer vintage, Integer isPost,
                                                         Integer registerStatus, String contactPerson, String applicantName) {

        // 当前角色是否是团省委
        Integer isTsw = null;
        Account account = userInfoHolder.getAccount();
        Integer role = account.getRole();
        // 团省委 只查询上报的信息
        if(RoleEnum.SUPER_ADMIN.getCode() == role){
            isPost = TrueOrFalseEnum.TRUE.getType();
            isTsw = TrueOrFalseEnum.TRUE.getType();
        }
        PageHelper.startPage(pageNum, pageSize);
        return applicantDao.listReferencePage(orgPath, vintage,  isPost,
                registerStatus, contactPerson,  applicantName, isTsw);
    }

    private List<ApplicantReferenceListVO> selectByRole(String orgPath, Integer vintage, Integer isPost,
                                                        Integer registerStatus, String contactPerson, String applicantName) {

        // 1. 查看当前角色
        Account account = userInfoHolder.getAccount();
        Integer role = account.getRole();
        Integer isTop = 1;
        // 团省委 只查询上报的信息
        if(RoleEnum.SUPER_ADMIN.getCode() == role){
            isTop = null;
            isPost = TrueOrFalseEnum.TRUE.getType();
        }
        return applicantDao.listReferencePage(orgPath, vintage,  isPost, registerStatus, contactPerson,  applicantName, isTop);
    }



    @Override
    public void downloadReview(Long orgId, String applicantName, String contactPerson, Integer status,
                               Integer applicantStatus, Boolean submitted, Integer reviewType, Integer registerStatus,
                               Date startTime, Date endTime) {
        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            ExcelUtil.export(new ArrayList<>(), ApplicantExportVO.getHeaderAlias(), "集体信息.xlsx");
            return;
        }
        applicantName = StringUtils.trimToNull(applicantName);
        contactPerson = StringUtils.trimToNull(contactPerson);

        List<ApplicantExportDTO> applicantDTOS = applicantDao.listExportApplicants(organization.getOrgPath(), applicantName,
                contactPerson, status, applicantStatus, submitted, reviewType, registerStatus, startTime, endTime);
        for (int i = 0; i < applicantDTOS.size(); i++) {
            applicantDTOS.get(i).fill(i + 1);
        }

        ExcelUtil.export(applicantDTOS, ApplicantExportDTO.getHeaderAlias(), "集体信息.xlsx");
    }

    @Override
    public void approveRegister(Long applicantId, Long accountId, Long orgId) {
        Applicant applicant = applicantDao.selectById(applicantId);
        if (applicant == null) {
            throw new ServiceException("集体不存在或已失效");
        }
        Organization selfOrg = organizationDao.selectById(applicant.getOrgId());
        if (selfOrg == null) {
            throw new ServiceException("集体机构不存在或已失效");
        }
        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            throw new ServiceException("审核机构不存在或已失效");
        }
        Admin admin = adminDao.getByAccountId(accountId);
        if (admin == null) {
            throw new ServiceException("审核管理员不存在或已失效");
        }
        if (organization.getOrgRole() == RoleEnum.SUPER_ADMIN.getCode()) {
            if (applicant.getRegisterTitle() > TitleEnum.CITY.getType()) {
                Applicant approvedApplicant = new Applicant();
                approvedApplicant.setId(applicantId);
                approvedApplicant.setRegisterStatus(RegisterStatusEnum.PROVINCE_TITLE.getCode());
                approvedApplicant.setTitle(applicant.getRegisterTitle());
                applicantDao.updateById(approvedApplicant);
                StandingBookReviewLog log = new StandingBookReviewLog();
                log.setReviewType(RegisterStatusEnum.PROVINCE_TITLE.getCode());
                log.setReviewAdminId(admin.getId());
                log.setApplicantId(applicantId);
                log.setAction("通过");
                standingBookReviewLogDao.insert(log);
            }
        } else if (organization.getOrgRole() == RoleEnum.SECOND_ADMIN.getCode()) {
            if (applicant.getReviewType() == ReviewTypeEnum.JOIN.getCode()) {
                Applicant approvedApplicant = new Applicant();
                approvedApplicant.setId(applicantId);
                approvedApplicant.setRegisterStatus(RegisterStatusEnum.CITY_TITLE.getCode());
                approvedApplicant.setTitle(TitleEnum.CITY.getType());
                approvedApplicant.setRegisterTitle(TitleEnum.CITY.getType());
                approvedApplicant.setJoinReviewPass(JoinReviewStatusEnum.SUCCESS.getType());
                applicantDao.updateById(approvedApplicant);
            } else {
                Applicant approvedApplicant = new Applicant();
                approvedApplicant.setId(applicantId);
                approvedApplicant.setRegisterStatus(RegisterStatusEnum.CITY_TITLE.getCode());
                approvedApplicant.setTitle(TitleEnum.CITY.getType());
                approvedApplicant.setRegisterTitle(TitleEnum.CITY.getType());
                applicantDao.updateById(approvedApplicant);
            }
            StandingBookReviewLog log = new StandingBookReviewLog();
            log.setReviewType(RegisterStatusEnum.CITY_TITLE.getCode());
            log.setReviewAdminId(admin.getId());
            log.setApplicantId(applicantId);
            log.setAction("通过");
            standingBookReviewLogDao.insert(log);
        } else if (organization.getOrgRole() == RoleEnum.LOWER_ADMIN.getCode()) {
            if (applicant.getRegisterStatus() == RegisterStatusEnum.REGISTER.getCode()) {
                Applicant approvedApplicant = new Applicant();
                approvedApplicant.setId(applicantId);
                approvedApplicant.setRegisterStatus(RegisterStatusEnum.CITY_REVIEW.getCode());
                approvedApplicant.setTitleYear(DateUtil.format(new Date(), "yyyy"));
                applicantDao.updateById(approvedApplicant);
            }
            StandingBookReviewLog log = new StandingBookReviewLog();
            log.setReviewType(RegisterStatusEnum.CITY_REVIEW.getCode());
            log.setReviewAdminId(admin.getId());
            log.setApplicantId(applicantId);
            log.setAction("通过");
            standingBookReviewLogDao.insert(log);
        }
    }

    @Override
    @Transactional
    public void denyRegister(Long applicantId, Long accountId, Long orgId, String cause) {
        Applicant applicant = applicantDao.selectById(applicantId);
        if (applicant == null) {
            throw new ServiceException("集体不存在或已失效");
        }
        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            throw new ServiceException("审核机构不存在或已失效");
        }
        Admin admin = adminDao.getByAccountId(accountId);
        if (admin == null) {
            throw new ServiceException("审核管理员不存在或已失效");
        }
        if (organization.getOrgRole() == RoleEnum.SUPER_ADMIN.getCode()) {
            StandingBookReviewLog log = new StandingBookReviewLog();
            log.setReviewType(RegisterStatusEnum.PROVINCE_TITLE.getCode());
            log.setReviewAdminId(admin.getId());
            log.setApplicantId(applicantId);
            log.setAction("不通过");
            log.setCause(cause);
            standingBookReviewLogDao.insert(log);
        } else if (organization.getOrgRole() == RoleEnum.SECOND_ADMIN.getCode()) {
            StandingBookReviewLog log = new StandingBookReviewLog();
            log.setReviewType(RegisterStatusEnum.CITY_TITLE.getCode());
            log.setReviewAdminId(admin.getId());
            log.setApplicantId(applicantId);
            log.setAction("不通过");
            log.setCause(cause);
            standingBookReviewLogDao.insert(log);
        } else if (organization.getOrgRole() == RoleEnum.LOWER_ADMIN.getCode()) {
            StandingBookReviewLog log = new StandingBookReviewLog();
            log.setReviewType(RegisterStatusEnum.CITY_REVIEW.getCode());
            log.setReviewAdminId(admin.getId());
            log.setApplicantId(applicantId);
            log.setAction("不通过");
            log.setCause(cause);
            standingBookReviewLogDao.insert(log);
        }
    }

    @Override
    public ApplicantVO getByApplicantId(Long applicantId) {
        Applicant applicant = applicantDao.selectById(applicantId);
        if (applicant == null) {
            throw new ServiceException("集体不存在或已失效");
        }
        Account account = accountDao.selectById(applicant.getAccountId());
        if (account == null) {
            throw new ServiceException("集体的账号已失效");
        }
        Organization organization = organizationDao.selectById(applicant.getOrgId());

        String allOrganization = organizationService.getAllName(organization);

        if (organization == null) {
            throw new ServiceException("集体所在的组织机构已失效");
        }
        organization.setOrgName(allOrganization);

        Organization joinOrg = null;
        if (applicant.getReviewType() == ReviewTypeEnum.JOIN.getCode()) {
            joinOrg = organizationDao.selectById(applicant.getJoinReviewOrgId());
            if (joinOrg == null) {
                throw new ServiceException("联合审核机构不存在或已失效");
            }
            String joinAllName = organizationService.getAllName(joinOrg);
            joinOrg.setOrgName(joinAllName);
        }

        return ApplicantVO.build(account, applicant, organization, joinOrg, documentProperties.getUrl());
    }

    @Override
    public void batchApproveRegister(List<Long> applicantIds, Long accountId, Long orgId) {
        if (CollectionUtils.isEmpty(applicantIds)) {
            return;
        }
        applicantIds.forEach(applicantId -> approveRegister(applicantId, accountId, orgId));
    }

    @Override
    public void batchDenyRegister(List<Long> applicantIds, Long accountId, Long orgId) {
        if (CollectionUtils.isEmpty(applicantIds)) {
            return;
        }
        applicantIds.forEach(applicantId -> denyRegister(applicantId, accountId, orgId, ""));
    }

    @Override
    public List<StandingBookReviewLogVO> getLog(Long applicantId, Integer type) {
        List<StandingBookReviewLogDTO> logs = standingBookReviewLogDao.listByAccountId(applicantId, type);
        Long maxReferenceId = referenceDao.getMaxId(applicantId);
        List<StandingBookReviewLogDTO> referenceLogs = referenceReviewLogService.listByAccountId(applicantId, type, maxReferenceId);
        logs.addAll(referenceLogs);

        return logs.stream()
                .map(StandingBookReviewLogDTO::build)
                .collect(Collectors.toList());
    }

    @Override
    public List<StandingBookReviewLogVO> getLogByAccountId(Long accountId, Integer type) {
        Applicant applicant = applicantDao.getByAccountId(accountId);
        if (applicant == null) {
            throw new ServiceException("集体已失效");
        }
        List<StandingBookReviewLogDTO> logs = standingBookReviewLogDao.listByAccountId(applicant.getId(), type);
        List<StandingBookReviewLogDTO> referenceLogs = referenceReviewLogService.listByAccountId(applicant, type);
        logs.addAll(referenceLogs);

        return logs.stream()
                .map(StandingBookReviewLogDTO::build)
                .collect(Collectors.toList());
    }

    @Override
    public void updateCheckDoc(String fileUrl, Long applicantId) {

        if(ObjectUtil.isNull(applicantId)){
            Long accountId = userInfoHolder.getAccountId();
            applicantId = applicantDao.getByAccountId(accountId).getId();
        }

        Applicant applicant = getById(applicantId);
        if(applicant == null){
            throw new ServiceException("集体已失效");
        }
        applicant.setCheckDoc(fileUrl);
        updateById(applicant);
    }

    @Override
    public void applicantReferenceExport( Integer vintage, Long orgId, Integer isPost, Integer registerStatus, String contactPerson, String applicantName   ) {

        // 参数预处理
        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
        }
        applicantName = StringUtils.trimToNull(applicantName);
        contactPerson = StringUtils.trimToNull(contactPerson);

        List<ApplicantReferenceListVO> applicantReferenceListVOS = selectByRole(organization.getOrgPath(), vintage, isPost,
                registerStatus, contactPerson, applicantName);
        List<ApplicantReferenceExportDTO> result = new ArrayList<>();
        List<Long> ids = applicantReferenceListVOS.stream().map(ApplicantReferenceListVO::getId).collect(Collectors.toList());
        Map<Long, List<ReferenceEntity>> idMapReferenceEntity = referenceService.listByIds(ids).stream().collect(Collectors.groupingBy(ReferenceEntity::getId));

        for (int i = 0; i < applicantReferenceListVOS.size(); i++) {

            ApplicantReferenceListVO applicantReferenceListVO = applicantReferenceListVOS.get(i);
            applicantReferenceListVO.build();
            ApplicantReferenceExportDTO  applicantReferenceExportDTO = new ApplicantReferenceExportDTO();
            BeanUtil.copyProperties(applicantReferenceListVO, applicantReferenceExportDTO);
            applicantReferenceExportDTO.setNumber(Long.valueOf(i + 1));
            applicantReferenceExportDTO.setApplyTime(DateUtil.format(applicantReferenceListVO.getApplyTime(), "yyyy-MM-dd"));
            applicantReferenceExportDTO.setReviewTypeStr(ReviewTypeEnum.getByCode(applicantReferenceListVO.getReviewType()).getMessage());
            applicantReferenceExportDTO.setTitleStr(TitleEnum.getByType(applicantReferenceListVO.getTitle()).getDescription());
            applicantReferenceExportDTO.setAllowTime(applicantReferenceListVO.getTitleYear());
            ReferenceEntity referenceEntitie = idMapReferenceEntity.get(applicantReferenceListVO.getId()).get(0);
            String reportOrgName = "";
            Organization org = organizationService.getById(referenceEntitie.getOrgId());
            reportOrgName = org.getOrgName();
            Integer reviewType = referenceEntitie.getReviewType();
            if(ReviewTypeEnum.JOIN.getCode().equals(reviewType)){
                Organization joinOrg = organizationService.getById(referenceEntitie.getJoinReviewOrgId());
                reportOrgName += "/"+joinOrg.getOrgName();
            }
            applicantReferenceExportDTO.setReportOrgName(reportOrgName);
            result.add(applicantReferenceExportDTO);
        }
        ExcelUtil.export(result, ApplicantReferenceExportDTO.getHeaderAlias(), "测评信息.xlsx");
    }


    @Override
    public Applicant getEntityByAccountId(Long accountId) {

        return applicantDao.getByAccountId(accountId);
    }

    @Override
    public Integer getHint() {

        Applicant applicant = applicantDao.getByAccountId(userInfoHolder.getAccountId());
        Integer registerStatus = applicant.getRegisterStatus();

        if(Integer.valueOf(RegisterStatusEnum.PROVINCE.getCode()) == registerStatus){
            ReferenceEntity referenceEntity = referenceDao.selectByApplicantId(applicant.getId(), DateUtil.format(new Date(), "yyyy"));
            if (referenceEntity != null ){
                Integer reviewStatus = referenceEntity.getReviewStatus();
                if(reviewStatus == 4){
                    return 7;
                }
            }
        }
        return registerStatus;
    }

    @Override
    public Page<ApplicantReferenceListVO> submitAgain(Integer pageNum, Integer pageSize, Long orgId) {

        // 参数预处理
        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            return null;
        }
        // 查询驳回后提交的文明号
        List<Long> referenceIds = referenceReviewLogService.getSubmitAgainIds(userInfoHolder.getAccount().getRole());
        // 分页查询
        PageHelper.startPage(pageNum, pageSize);
        List<ApplicantReferenceListVO> applicantReferenceListVOS = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(referenceIds)){
            applicantReferenceListVOS = applicantDao.submitAgainIdsPage(organization.getOrgPath(), referenceIds);
        }
        PageInfo<ApplicantReferenceListVO> pageInfo = new PageInfo<>(applicantReferenceListVOS);

        // 返回数据处理
        for (ApplicantReferenceListVO applicantReferenceListVO : applicantReferenceListVOS) {
            applicantReferenceListVO.build();
            Long id = applicantReferenceListVO.getId();
            ReferenceDetailVO referenceDetailVO = referenceService.detail(id);
            applicantReferenceListVO.setRecommend(referenceDetailVO.getRecommend());
            applicantReferenceListVO.setStory(referenceDetailVO.getStory());
            applicantReferenceListVO.setEvidences(referenceDetailVO.getEvidences());
            applicantReferenceListVO.setEvidenceLinks(referenceDetailVO.getEvidenceLinks());
        }
        return new Page<ApplicantReferenceListVO>().setPageNum(pageInfo.getPageNum())
                .setPageSize(pageInfo.getPageSize())
                .setPages(pageInfo.getPages())
                .setTotal(pageInfo.getTotal())
                .setContent(applicantReferenceListVOS);
    }

    @Override
    public Integer submitAgainNumber(Long orgId) {

        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            return null;
        }
        // 查询驳回后提交的文明号
        List<Long> referenceIds = referenceReviewLogService.getSubmitAgainIds(userInfoHolder.getAccount().getRole());
        List<ApplicantReferenceListVO> applicantReferenceListVOS = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(referenceIds)){
            applicantReferenceListVOS = applicantDao.submitAgainIdsPage(organization.getOrgPath(), referenceIds);
        }
        return applicantReferenceListVOS.size();
    }




    @Override
    public void resetPassword(Long applicantId) {
        Applicant applicant = applicantDao.selectById(applicantId);
        if (applicant == null) {
            throw new ServiceException("集体已失效");
        }
        accountManager.resetPassword(applicant.getAccountId());
    }

    @Override
    @Transactional
    public void delete(List<Long> applicantIds, Long orgId) {
        if (CollectionUtils.isEmpty(applicantIds)) {
            return;
        }
        List<Applicant> applicants = applicantDao.selectBatchIds(applicantIds);
        if (CollectionUtils.isEmpty(applicants)) {
            return;
        }
        Organization organization = organizationDao.selectById(orgId);
        if (organization == null) {
            throw new ServiceException("组织机构已失效");
        }
        if (organization.getOrgRole() == RoleEnum.LOWER_ADMIN.getCode()) {
            for (Applicant applicant : applicants) {
                if (applicant.getTitle() > TitleEnum.NO.getType()) {
                    throw new ServiceException("该单位已经授予文明号，您没有删除权限。请联系此单位的文明号命名授予机关。");
                }
            }
        }

        List<Long> accountIds = applicants.stream().map(Applicant::getAccountId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(accountIds)) {
            accountManager.deleteByIds(accountIds);
            standingBookDao.deleteByAccountIds(accountIds);
            standingBookDocumentDao.deleteByAccountIds(accountIds);
            standingBookReviewDao.deleteByAccountIds(accountIds);
        }
        applicantDao.deleteBatchIds(applicantIds);
    }

    @Override
    public ApplicantContactVO getContact(Long applicantId) {
        Applicant applicant = applicantDao.selectById(applicantId);
        if (applicant == null) {
            throw new ServiceException("集体已失效");
        }
        return ApplicantContactVO.build(applicant);
    }

    @Override
    public void updateContact(ApplicantContactUpdateDTO applicantContactUpdateDTO) {
        Applicant applicant = applicantContactUpdateDTO.build();
        applicantDao.updateById(applicant);
    }

}
